/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.flexengine.logger;

import java.util.*;

/**
 * @author Luann R. Athayde
 * @version 1.0
 * @since 1.0
 */
public class LinkedLogger {

    public static final int START_ID = 1000;
    
    private int        loggerDataID;

    private int        maxSize;
    private int        size;
    
    private DataLogger init;
    private DataLogger end;
    private DataLogger current;

    public LinkedLogger() {
        loggerDataID = START_ID;
        maxSize = 128;
        size    = 0;
        init    = null;
        end     = null;
        current = null;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return init == null && size == 0;
    }

    public boolean add(DataLogger e) throws FullLoggerException {
        if( size == maxSize ) {
            throw new FullLoggerException("This logger is full! Please clear the logger or remove an object...");
        }
        try {
            e.setId(loggerDataID);
            loggerDataID++;
            if( init == null ) {
                init = end = current = e;
            } else {
                end.setProx(e);
                DataLogger tmp = end;
                end = e;
                end.setAnt(tmp);
            }
            size++;
            return true;
        } catch(Exception ex) {
            System.err.println(ex);
            return false;
        }
    }

    public boolean remove(Object o) {
        try {
            if( o instanceof DataLogger ) {
                DataLogger comp = (DataLogger) o;
                DataLogger tmp = init;
                while( tmp != null ) {
                    if( tmp.getId() == comp.getId() ) {
                        tmp.getAnt().setProx(tmp.getProx());
                        tmp.getProx().setAnt(tmp.getAnt());
                        if( current == tmp )
                            current = init;
                        tmp = comp = null;
                        size--;
                        return true;
                    }
                    else
                        tmp = tmp.getProx();
                }
            }
        } catch(Exception ex) {
            System.err.println(ex);
        }
        return false;
    }

    public boolean removeAll(Collection<?> c) {
        int sz = c.size();
        int rm = 0;
        try {
            for(Object o : c)   {
                if( o instanceof DataLogger ) {
                    DataLogger comp = (DataLogger) o;
                    DataLogger tmp = init;
                    while( tmp != null ) {
                        if( tmp.getId() == comp.getId() ) {
                            tmp.getAnt().setProx(tmp.getProx());
                            tmp.getProx().setAnt(tmp.getAnt());
                            if( current == tmp )
                                current = init;
                            tmp = comp = null;
                            rm++;
                        }
                        else
                            tmp = tmp.getProx();
                    }
                }
            }
        } catch(Exception ex) {
            System.err.println(ex);
        }
        size -= rm;
        if( rm == sz )
            return true;
        return false;
    }

    public synchronized void clear() {
        DataLogger tmp1 = end;
        DataLogger tmp2 = null;
        while( tmp1 != null ) {
            tmp2 = tmp1.getAnt();
            tmp1.setAnt(null);
            tmp1.setProx(null);
            tmp1 = null;
            tmp1 = tmp2;
        }
        init = current = end = null;
        size = 0;
        System.gc();
    }

    public DataLogger get(int id) {
        DataLogger tmp = init;
        while( tmp != null ) {
            if( tmp.getId() == id ) {
                return tmp;
            }
            else
                tmp = tmp.getProx();
        }
        return null;
    }

    public DataLogger set(int id, DataLogger element) throws Exception {
        DataLogger tmp = init;
        while( tmp != null ) {
            if( tmp.getId() == id ) {
                element.setId(id);
                tmp = element;
                return tmp;
            }
            else
                tmp = tmp.getProx();
        }
        return null;
    }

    public void add(int id, DataLogger element) throws FullLoggerException {
        if( size == maxSize ) throw new FullLoggerException("This logger is full! Please clear the logger or remove an object...");
        boolean overrid = false;
        DataLogger tmp = init;
        while( tmp != null ) {
            if( tmp.getId() == id ) {
                tmp = element;
                overrid = true;
                break;
            }
            else
                tmp = tmp.getProx();
        }
        if( !overrid ) {
            element.setId(id);
            tmp = end;
            tmp.setProx(element);
            element.setAnt(tmp);
            end = element;
            size++;
        }
    }

    public DataLogger remove(int id) {
        DataLogger tmp = init;
        while( tmp != null ) {
            if( tmp.getId() == id ) {
                tmp.getAnt().setProx(tmp.getProx());
                tmp.getProx().setAnt(tmp.getAnt());
                size--;
                return tmp;
            }
            else
                tmp = tmp.getProx();
        }
        return null;
    }

    public boolean contains(Object o) {
        if( o instanceof DataLogger ) {
            DataLogger tmp = init;
            DataLogger cmp = (DataLogger) o;
            while( tmp != null ) {
                if( tmp.getId() == cmp.getId() ) {
                    return true;
                }
                else
                    tmp = tmp.getProx();
            }
        }
        return false;
    }
    public Object[] toArray() {
        DataLogger objs[] = new DataLogger[size];
        DataLogger tmp = init;
        int i = 0;
        while( tmp != null ) {
            objs[i] = tmp;
            tmp = tmp.getProx();
            i++;
        }
        return objs;
    }
    public int getMaxSize() {
        return maxSize;
    }
    public void setMaxSize(int maxSize) {
        if( maxSize < 1 ) maxSize = 1;
        this.maxSize = maxSize;
    }

    public DataLogger getLast() {
        return end;
    }
    
}